package com.meeting.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.meeting.dto.*;
import com.meeting.entity.Orders;
import com.meeting.entity.Rooms;
import com.meeting.mapper.OrdersMapper;
import com.meeting.mapper.RoomEquipmentMapper;
import com.meeting.mapper.RoomsMapper;
import com.meeting.service.RoomsService;
import com.meeting.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import static com.fasterxml.jackson.databind.type.LogicalType.Map;

@Service
@Slf4j
public class RoomsServiceImpl extends ServiceImpl<RoomsMapper, Rooms> implements RoomsService {
    @Autowired
    private RoomsMapper roomMapper;
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private RoomEquipmentMapper roomEquipmentMapper;
    @Autowired
    private RoomsMapper roomsMapper;

    @Override
    public PageResult<RoomsVO> listRooms(RoomQueryDTO roomQueryDTO) {
        if (roomQueryDTO.getSupport() != null && !roomQueryDTO.getSupport().isEmpty()) {
            roomQueryDTO.setNum(roomQueryDTO.getSupport().size());
            log.info("设备需求过滤：需要设备类型ID列表 = {}, 总数 = {}",
                    roomQueryDTO.getSupport(), roomQueryDTO.getNum());
        } else {
            roomQueryDTO.setNum(null);
        }

        // 记录名称和分类搜索条件
        if (roomQueryDTO.getName() != null && !roomQueryDTO.getName().isEmpty()) {
            log.info("按名称搜索：{}", roomQueryDTO.getName());
        }
        
        if (roomQueryDTO.getCategoryId() != null) {
            log.info("按分类搜索：分类ID = {}", roomQueryDTO.getCategoryId());
        }

        // 🔧 修正：时间处理 - 将时间精确到小时
        if (roomQueryDTO.getStartTime() != null && roomQueryDTO.getEndTime() != null) {
            roomQueryDTO.setStartTime(normalizeToHour(roomQueryDTO.getStartTime()));
            roomQueryDTO.setEndTime(normalizeToHour(roomQueryDTO.getEndTime()));
            log.info("时间范围过滤：{} 到 {}", roomQueryDTO.getStartTime(), roomQueryDTO.getEndTime());
        }

        // 获取满足设备要求的会议室ID
        List<Integer> roomIds = roomMapper.listAllRooms(roomQueryDTO);
        log.info("满足搜索条件的会议室数量：{}", roomIds != null ? roomIds.size() : 0);

        // 排除时间冲突的会议室
        if (roomQueryDTO.getStartTime() != null && roomQueryDTO.getEndTime() != null) {
            List<Integer> conflictIds = ordersMapper.selectByStartAndEndTime(
                    roomQueryDTO.getStartTime(), roomQueryDTO.getEndTime());
            if (conflictIds != null && !conflictIds.isEmpty()) {
                roomIds.removeAll(conflictIds);
                log.info("排除时间冲突后的会议室数量：{}", roomIds.size());
            }
        }

        if (roomIds == null || roomIds.isEmpty()) {
            return new PageResult<>(0L, Collections.emptyList());
        }

        // 分页查询
        PageHelper.startPage(roomQueryDTO.getPage(), roomQueryDTO.getPageSize());
        Page<RoomsVO> rooms = roomMapper.queryRoomsByIds(roomIds);

        // 查询并设置设备信息
        List<RoomEquipmentDTO> equipmentList = roomEquipmentMapper.selectDeviceNamesByRoomIds(roomIds);
        Map<Integer, List<String>> supportMap = equipmentList.stream()
                .collect(Collectors.groupingBy(
                        RoomEquipmentDTO::getRoomsId,
                        Collectors.mapping(RoomEquipmentDTO::getDeviceName, Collectors.toList())
                ));

        rooms.forEach(room -> {
            List<String> supportList = supportMap.getOrDefault(room.getId(), Collections.emptyList());
            room.setSupport(supportList);
        });

        return new PageResult<>(rooms.getTotal(), rooms.getResult());
    }

    @Override
    public boolean checkRoomAvailability(RoomAvailabilityDTO availabilityDTO) {
        try {
            log.info("检查会议室可用性：{}", availabilityDTO);

            Integer roomId = availabilityDTO.getRoomId();

            // 🔧 修正：时间标准化到小时
            String startTimeStr = normalizeToHour(availabilityDTO.getStartTime());
            String endTimeStr = normalizeToHour(availabilityDTO.getEndTime());

            // 检查会议室是否存在且可用
            Rooms room = roomsMapper.selectById(roomId);
            if (room == null) {
                log.warn("会议室不存在，ID：{}", roomId);
                return false;
            }

            // 检查会议室状态（1为可用）
            if (room.getStatus() != null && room.getStatus() != 1) {
                log.warn("会议室不可用，状态：{}，ID：{}", room.getStatus(), roomId);
                return false;
            }

            // 检查时间冲突
            List<Integer> conflictIds = ordersMapper.selectByStartAndEndTime(startTimeStr, endTimeStr);
            boolean isAvailable = conflictIds == null || !conflictIds.contains(roomId);

            log.info("会议室可用性检查结果：{}，会议室ID：{}", isAvailable, roomId);
            return isAvailable;

        } catch (Exception e) {
            log.error("检查会议室可用性失败", e);
            return false;
        }
    }

    // 🔧 新增：时间标准化方法 - 将时间精确到小时
    private String normalizeToHour(String timeStr) {
        if (timeStr == null || timeStr.trim().isEmpty()) {
            return timeStr;
        }

        try {
            // 尝试解析时间并标准化到小时
            LocalDateTime dateTime;
            if (timeStr.length() <= 16) { // yyyy-MM-dd HH:mm 格式
                dateTime = LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            } else { // yyyy-MM-dd HH:mm:ss 格式
                dateTime = LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }

            // 截断到小时，分钟和秒设为0
            LocalDateTime normalizedTime = dateTime.truncatedTo(ChronoUnit.HOURS);
            return normalizedTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        } catch (Exception e) {
            log.warn("时间格式标准化失败，原始时间：{}，错误：{}", timeStr, e.getMessage());
            return timeStr;
        }
    }

    @Override
    public RoomsVO getRoomDetail(Integer id) {
        try {
            log.info("获取会议室详情，ID：{}", id);

            // 使用自定义查询获取包含分类名称的会议室信息
            List<Integer> ids = Arrays.asList(id);
            Page<RoomsVO> roomsPage = roomMapper.queryRoomsByIds(ids);
            if (roomsPage == null || roomsPage.isEmpty()) {
                log.warn("会议室不存在，ID：{}", id);
                return null;
            }
            
            RoomsVO roomsVO = roomsPage.get(0);

            // 查询会议室设备支持信息
            List<RoomEquipmentDTO> equipmentList = roomEquipmentMapper.selectDeviceNamesByRoomIds(Arrays.asList(id));
            List<String> supportList = equipmentList.stream()
                    .map(RoomEquipmentDTO::getDeviceName)
                    .collect(Collectors.toList());
            roomsVO.setSupport(supportList);

            log.info("获取会议室详情成功，会议室：{}", roomsVO.getName());
            return roomsVO;

        } catch (Exception e) {
            log.error("获取会议室详情失败，ID：{}", id, e);
            return null;
        }
    }

//        if(roomQueryDTO.getSupport()!=null && !roomQueryDTO.getSupport().isEmpty()){
//            roomQueryDTO.setNum(roomQueryDTO.getSupport().size());
//        }else {
//            roomQueryDTO.setNum(null);
//        }
//        List<Integer> roomIds = roomMapper.listAllRooms(roomQueryDTO);
//        List<Integer> conflictIds = ordersMapper.selectByStartAndEndTime(roomQueryDTO.getStartTime(),roomQueryDTO.getEndTime());
//        if(conflictIds!=null){
//            roomIds.removeAll(conflictIds);
//        }
//        if(roomIds == null || roomIds.isEmpty()){
//            return new PageResult<>(0L, Collections.emptyList());
//        }
//        PageHelper.startPage(roomQueryDTO.getPage(),roomQueryDTO.getPageSize());
//        Page<RoomsVO> rooms = roomMapper.queryRoomsByIds(roomIds);
//
//        List<RoomEquipmentDTO> equipmentList = roomEquipmentMapper.selectDeviceNamesByRoomIds(roomIds);
//        Map<Integer,List<String>> supportMap = equipmentList.stream()
//                .collect(Collectors.groupingBy(
//                        RoomEquipmentDTO::getRoomsId,
//                        Collectors.mapping(RoomEquipmentDTO::getDeviceName,Collectors.toList())
//                ));
//
//        rooms.forEach(room->{
//            List<String> supportList = supportMap.getOrDefault(room.getId(),Collections.emptyList());
//            room.setSupport(supportList);
////            room.setSupportText(String.join(", ", supportList));
//        });
//        return new PageResult<>(rooms.getTotal(),rooms.getResult());
//    }

    @Override
    public RoomGridStatusVO getRoomStatusGrid(RoomStatusQueryDTO dto) {
        List<Rooms> rooms = roomMapper.selectAll(dto);
        List<RoomSimpleVO> roomsList = rooms.stream()
                .map(r -> {
                    RoomSimpleVO vo = new RoomSimpleVO(r.getId(), r.getName(), r.getStatus());
                    /*vo.setCategoryName(r.getCategoryName()); // 设置分类名称*/
                    return vo;
                })
                .collect(Collectors.toList());

        LocalDate date = dto.getDate();

        List<TimeSlotStatusVO> timeSlots = new ArrayList<>();
        for(int hour = 8 ; hour < 21 ; hour++){
            LocalDateTime start = date.atTime(hour,0);
            LocalDateTime end = date.atTime(hour+1,0);

            List<Orders> orders = ordersMapper.selectOrdersInTimeRange(start,end);

            TimeSlotStatusVO slot = new TimeSlotStatusVO();
            slot.setTime(String.format("%02d:00-%02d:00",hour,hour + 1));
            Map<Integer,String> statusMap = new HashMap<>();

            for(Rooms room : rooms){
                String status = "空闲";


                for(Orders order:orders){
                    if(order.getRoomId().equals(room.getId())){
                        if(order.getStatus()==2 && LocalDateTime.now().isBefore(order.getEndTime())){
                            status = "使用";
                            break;
                        }else if(order.getStatus()==1 && LocalDateTime.now().isBefore(order.getStartTime())){
                            status = "预定";
                        }else if(order.getStatus()==0 && LocalDateTime.now().isBefore(order.getStartTime())){
                            status = "锁定";
                        }else if(order.getStatus()==3 && LocalDateTime.now().isAfter(order.getEndTime())){
                            status = "已完成";
                        }
                    }
                }

                if(room.getStatus() != null && room.getStatus() == 2){
                    status = "维护";
                }

                statusMap.put(room.getId(),status);
            }
            slot.setStatusMap(statusMap);
            timeSlots.add(slot);
        }
        RoomGridStatusVO result = new RoomGridStatusVO();
        result.setRoomList(roomsList);
        result.setTimeSlots(timeSlots);
        return result;
    }

    @Override
    public void setRoomsStatus(Integer roomId, Integer status) {
        Rooms rooms = roomsMapper.selectById(roomId);
        rooms.setStatus(status);
        roomsMapper.updateById(rooms);
    }

    @Override
    public void setToUsing(RoomStatusUpdateDTO dto) {
        LocalDateTime timeSlotStart = dto.getTimeSlotStart();
        Orders order = ordersMapper.selectOrdersByRoomAndTime(dto.getRoomId(), timeSlotStart);
//        Orders order = ordersMapper.selectOrdersByRoomAndTime(dto.getRoomId(),dto.getTimeSlotStart());
        if(order!=null && order.getStatus() ==1){
            order.setStatus(2);
            ordersMapper.updateById(order);
        }
        /*Rooms rooms = roomMapper.selectById(dto.getRoomId());
        rooms.setStatus(2);
        roomsMapper.updateById(rooms);*/
    }

    @Override
    public void setToRepair(Integer roomId) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime repairTime = LocalDateTime.now().plusHours(2);
        boolean conflict = ordersMapper.existsOrderBetween(roomId, now, repairTime);
        if(conflict){
            throw new RuntimeException("改设计简超过1小时有预约，无法设置维修状态");
        }
        Rooms room =roomsMapper.selectById(roomId);
        room.setStatus(0);
        roomsMapper.updateById(room);
    }

    @Override
    public void setToIdle(Integer roomId) {
        Rooms room = roomsMapper.selectById(roomId);
        room.setStatus(1);
        roomsMapper.updateById(room);
    }

    @Override
    public boolean addRoom(RoomDTO roomDTO) {
        try {
            log.info("新增会议室：{}", roomDTO);
            
            // 1. 添加会议室基本信息
            Rooms room = new Rooms();
            BeanUtils.copyProperties(roomDTO, room);
            int result = roomsMapper.insert(room);
            
            if (result <= 0) {
                log.error("新增会议室基本信息失败");
                return false;
            }
            
            // 2. 添加会议室设备关联信息
            if (roomDTO.getEquipmentTypeIds() != null && !roomDTO.getEquipmentTypeIds().isEmpty()) {
                result = roomEquipmentMapper.insertBatch(room.getId(), roomDTO.getEquipmentTypeIds());
                if (result <= 0) {
                    log.error("新增会议室设备关联信息失败");
                    return false;
                }
            }
            
            log.info("新增会议室成功，ID：{}", room.getId());
            return true;
        } catch (Exception e) {
            log.error("新增会议室失败", e);
            return false;
        }
    }

    @Override
    public boolean updateRoom(RoomDTO roomDTO) {
        try {
            log.info("修改会议室，ID：{}，数据：{}", roomDTO.getId(), roomDTO);
            
            // 1. 检查会议室是否存在
            Rooms existingRoom = roomsMapper.selectById(roomDTO.getId());
            if (existingRoom == null) {
                log.error("会议室不存在，ID：{}", roomDTO.getId());
                return false;
            }
            
            // 2. 更新会议室基本信息
            Rooms room = new Rooms();
            BeanUtils.copyProperties(roomDTO, room);
            int result = roomsMapper.updateById(room);
            
            if (result <= 0) {
                log.error("修改会议室基本信息失败");
                return false;
            }
            
            // 3. 更新会议室设备关联信息
            // 3.1 删除原有关联
            roomEquipmentMapper.deleteByRoomId(roomDTO.getId());
            
            // 3.2 添加新关联
            if (roomDTO.getEquipmentTypeIds() != null && !roomDTO.getEquipmentTypeIds().isEmpty()) {
                result = roomEquipmentMapper.insertBatch(roomDTO.getId(), roomDTO.getEquipmentTypeIds());
                if (result <= 0) {
                    log.error("修改会议室设备关联信息失败");
                    return false;
                }
            }
            
            log.info("修改会议室成功，ID：{}", roomDTO.getId());
            return true;
        } catch (Exception e) {
            log.error("修改会议室失败", e);
            return false;
        }
    }

    @Override
    public boolean deleteRoom(Integer id) {
        try {
            log.info("删除会议室，ID：{}", id);
            
            // 1. 检查会议室是否存在
            Rooms existingRoom = roomsMapper.selectById(id);
            if (existingRoom == null) {
                log.error("会议室不存在，ID：{}", id);
                return false;
            }
            
            // 2. 检查会议室是否有未完成的预约
            int count = ordersMapper.countActiveOrdersByRoomId(id);
            if (count > 0) {
                log.error("会议室存在未完成的预约，无法删除，ID：{}", id);
                return false;
            }
            
            // 3. 删除会议室设备关联
            roomEquipmentMapper.deleteByRoomId(id);
            
            // 4. 删除会议室
            int result = roomsMapper.deleteById(id);
            if (result <= 0) {
                log.error("删除会议室失败");
                return false;
            }
            
            log.info("删除会议室成功，ID：{}", id);
            return true;
        } catch (Exception e) {
            log.error("删除会议室失败", e);
            return false;
        }
    }

    @Override
    public boolean updateRoomStatus(Integer id, Integer status) {
        try {
            log.info("修改会议室状态，ID：{}，状态：{}", id, status);
            
            // 检查状态值是否合法
            if (status != 0 && status != 1 && status != 2) {
                log.error("会议室状态值不合法，状态：{}", status);
                return false;
            }
            
            // 检查会议室是否存在
            Rooms existingRoom = roomsMapper.selectById(id);
            if (existingRoom == null) {
                log.error("会议室不存在，ID：{}", id);
                return false;
            }
            
            // 如果设置为维护状态，检查是否有未完成的预约
            if (status == 0) {
                int count = ordersMapper.countActiveOrdersByRoomId(id);
                if (count > 0) {
                    log.error("会议室存在未完成的预约，无法设置为维护状态，ID：{}", id);
                    return false;
                }
            }
            
            // 更新状态
            Rooms room = new Rooms();
            room.setId(id);
            room.setStatus(status);
            int result = roomsMapper.updateById(room);
            
            if (result <= 0) {
                log.error("修改会议室状态失败");
                return false;
            }
            
            log.info("修改会议室状态成功，ID：{}，状态：{}", id, status);
            return true;
        } catch (Exception e) {
            log.error("修改会议室状态失败", e);
            return false;
        }
    }

    @Override
    public boolean checkRoomModifiable(Integer id) {
        try {
            log.info("检查会议室是否可修改或删除，ID：{}", id);
            
            // 检查会议室是否存在
            Rooms existingRoom = roomsMapper.selectById(id);
            if (existingRoom == null) {
                log.error("会议室不存在，ID：{}", id);
                return false;
            }
            
            // 检查是否有未完成的预约
            int count = ordersMapper.countActiveOrdersByRoomId(id);
            boolean canModify = count == 0;
            
            log.info("会议室是否可修改或删除：{}，ID：{}", canModify, id);
            return canModify;
        } catch (Exception e) {
            log.error("检查会议室是否可修改或删除失败", e);
            return false;
        }
    }
}